package recherche;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;


public class ModeleVectoriel extends Modele {

	public ModeleVectoriel(ArrayList<String> req) {
		super(req);
	}

	//@Override
	public HashMap<String, String> execute(HashMap<String,HashMap<Integer, Integer>> dfs,HashMap<Integer,ArrayList<String>> urlTitle) {

		//poid de chaque mot de la requete par document (dans les documents + requete)
		HashMap<String, HashMap<Integer, Double>> tfIdfs = tfIdf(urlTitle,dfs);

		//tableau pour stocker les 15 meilleurs resultats
		HashMap<Integer, Double> tabSim = new HashMap<Integer, Double>();

		//documents où apparaissent les mots de la requete
	
		Vector<Integer> docs = new Vector<Integer>();
		for (Entry<String, HashMap<Integer, Double>> mot : tfIdfs.entrySet()){
			Set<Integer> set = mot.getValue().keySet(); //les documents du mot
			Iterator<Integer> it = set.iterator();
			while (it.hasNext()){ //pour chaque doc mot
				int docActuel = it.next();
				if (!docs.contains(docActuel)) 
					docs.add(docActuel);		
			}
		}

		
		double wMotDoc = 0;
		double wReqDoc = 0;
		double sum1 = 0;
		double sum2 = 0;
		double sum3 = 0;

		//pour chaque doc contenant au moins un des mot de la requete
		for (Integer numDoc : docs){
			sum1 = sum2 = sum3 = 0;
			
			for (int i_mot=0; i_mot<requeteNorm.size(); i_mot++){

				
				HashMap<Integer, Double> map = tfIdfs.get(requeteNorm.get(i_mot));
				if (map.containsKey(numDoc))
					wMotDoc = map.get(numDoc);
				else 
					wMotDoc = 0;
				wReqDoc = tfIdfs.get(requeteNorm.get(i_mot)).get(-1);

				sum1 += wMotDoc * wReqDoc;
				sum2 += wMotDoc * wMotDoc;
				sum3 += wReqDoc * wReqDoc;

			}
			if (sum2 !=0 && sum3!=0)
				tabSim.put(numDoc, sum1 / (Math.sqrt(sum2) * Math.sqrt(sum3)));
			else tabSim.put(numDoc, (0.0));
		}



		// Ajout des entrées de la map à une liste		 
		List<Entry<Integer, Double>> entries = new ArrayList<Map.Entry<Integer,Double>>(tabSim.entrySet());
		// Tri de la liste sur la valeur de l'entrée
		Collections.sort(entries, new Comparator<Entry<Integer, Double>>() {
			public int compare(final Entry<Integer, Double> e1, final Entry<Integer, Double> e2) {
				return -(e1.getValue().compareTo(e2.getValue()));
			}
		});
		
		
		if (entries.size()>21)
			entries.subList(20, entries.size()-1).clear();
		
		/*for (Entry<Integer, Double> e : entries){
			System.out.println("doc : "+e.getKey() + "-sim : "+e.getValue());
			
		}*/

		HashMap<String, String> retour = new HashMap<String, String>();

		for (Entry<Integer, Double> entry : entries) {
	
		    if (entry.getKey().equals(-1))
		    	continue;
		    System.out.println("doc : "+entry.getKey() + "-sim : "+entry.getValue());
		    retour.put(urlTitle.get(entry.getKey()).get(0), urlTitle.get(entry.getKey()).get(1));
		    
		}
		
		
	return retour;
	}
}

